<template>
  <div>
    <canvas id="cvs"></canvas>
  </div>
</template>
<script lang="ts">
import { defineComponent, onMounted } from "vue";

export default defineComponent({
  setup() {
    onMounted(() => {
      const cvs = document.getElementById("cvs") as any;
      const ctx = cvs.getContext("2d");
      const bl = 2;
      const fontSize = 20 * bl;
      const lineHeight = fontSize * 1.5;
      cvs.width = cvs.height = 400 * bl;
      cvs.style.width = cvs.style.height = `${cvs.width / bl}px`;
      ctx.lineWidth = 20 * bl;
      ctx.lineCap = "round";
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";
      ctx.font = fontSize + "px 微软雅黑";
      const data = [
        {
          text: "项目1进度",
          rate: 90,
          color: "#67c23a",
        },
        {
          text: "项目2进度",
          color: "#f56c6c",
          rate: 80,
        },
        {
          text: "项目3进度",
          color: "#909399",
          rate: 50,
        },
      ];
      data.forEach((v:any) => {
        v.runRate = 0;
        v.step = v.rate / 100;
      });
      const render = () => {
        ctx.clearRect(0, 0, cvs.width, cvs.height);
        data.forEach((v:any, i) => {
          const mt = ctx.lineWidth / 2 + i * ctx.lineWidth;
          const r = cvs.width / 2;
          ctx.beginPath();
          ctx.strokeStyle = "#eeeeee";
          ctx.arc(r, r, r - mt, 0, (Math.PI / 180) * 360);

          ctx.stroke();
          ctx.beginPath();
          ctx.strokeStyle = v.color;
          ctx.arc(r, r, r - mt, 0, (Math.PI / 180) * ((360 * v.runRate) / 100));
          ctx.stroke();
          ctx.fillStyle = v.color;
          if (v.runRate > v.rate) {
            v.runRate = v.rate;
          } else if (v.runRate < v.rate) {
            v.runRate += v.step;
          }
          ctx.fillText(
            `${v.text}：${v.rate.toFixed(0)}%`,
            cvs.width / 2,
            i * lineHeight +
              (cvs.height - lineHeight * data.length) / 2 +
              lineHeight / 2
          );
        });
        if (!data.every((v:any) => v.runRate === v.rate)) {
          requestAnimationFrame(render);
        }
      };
      render();
    });
  },
});
</script>
